package com.codemonkey.lq.qd.extend.impl;

import java.util.HashMap;
import java.util.Map;

/**
 *  Copy From Configuration.StrictMap<V> class  <br>
 * 主要为覆写的put
 * @author LQ
 *
 * @param <V>
 */
public class StrictMap<V> extends HashMap<String, V> {

	private static final long serialVersionUID = -4950446264854982944L;
	private String name;

	public StrictMap(String name, int initialCapacity, float loadFactor) {
		super(initialCapacity, loadFactor);
		this.name = name;
	}

	public StrictMap(String name, int initialCapacity) {
		super(initialCapacity);
		this.name = name;
	}

	public StrictMap(String name) {
		super();
		this.name = name;
	}

	public StrictMap(String name, Map<String, ? extends V> m) {
		super(m);
		this.name = name;
	}
	
	@Override
	public boolean containsKey(Object key) {
		//因为SConfiguration类中的addServiceDefinition方法会对这个方法进行判断
		//而Mybatis和本框架进行热备都是采用本类中的put方法中,先移除,再添加的方式;;所以应该是可行的
		return false;
	}

	@SuppressWarnings("unchecked")
	public V put(String key, V value) {
		// ThinkGem 如果现在状态为刷新，则刷新(先删除后添加)
		if (true) {
			remove(key);
		}
		// ThinkGem end
		if (containsKey(key)) {
			throw new IllegalArgumentException(name + " already contains value for " + key);
		}
		
		// 这里会导致一个问题
		//   1. 对于 #{}中的resultMap,如果采用简写的话,则会报错.原因就是下面这个代码,是以 shortKey : value 存放的. 热备时候会发现之前已经存过一次.就冲突了
		//   2. 考虑进行以全称的来进行存储.
		if (key.contains(".")) {
			final String shortKey = getShortName(key);
			if (super.get(shortKey) == null) {
				super.put(shortKey, value);
			} else {
				super.put(shortKey, (V) new Ambiguity(shortKey));
			}
		}
		return super.put(key, value);
	}

	public V get(Object key) {
		V value = super.get(key);
		if (value == null) {
			throw new IllegalArgumentException(name + " does not contain value for " + key);
		}
		if (value instanceof Ambiguity) {
			throw new IllegalArgumentException(
					((Ambiguity) value).getSubject()
							+ " is ambiguous in "
							+ name
							+ " (try using the full name including the namespace, or rename one of the entries)");
		}
		return value;
	}

	private String getShortName(String key) {
		final String[] keyparts = key.split("\\.");
		return keyparts[keyparts.length - 1];
	}

	protected static class Ambiguity {
		private String subject;

		public Ambiguity(String subject) {
			this.subject = subject;
		}

		public String getSubject() {
			return subject;
		}
	}
}